package smlab.view.ui
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;
	
	import smlab.utils.PopUpUtils;
	import smlab.utils.Trace_SM;
	import smlab.view.ui.UIEvent.UIEvent;

	public class Panel_SM extends UIComponent_SM
	{
		private var _loader:Loader;
		private var _isSaveLoader:Boolean=false;		//是否保存loader，以便从 loader 获取其它类定义。请调用 Panel_SM 的 getClassFromLoaderByName 以获取类定义。
		private var _isAddToHideAll:Boolean=false;	//是否监听【关闭所有面板】的全局UI事件。
		
		/**
		 * 	0 代表直接取 Loader.content 作为 UI；								GetUIType.isLoaderContent
		 * 	1 代表获取 Loader content 的子元件作为 UI； 						GetUIType.fromLoaderContentByChildName
		 * 	2 代表从 loader.contentLoaderInfo 的域中获取类并实例化作为 UI		GetUIType.getDefFromLoaderAppByName
		 */
		private var _getUIType:uint=0;					
		private var _isShowLoading:Boolean=false;		//是否显示 Loading
		private var _isShowCloseBtn:Boolean=false;		//是否显示 Loading
		private var _panelHideFun:Function;			//面板隐藏后执行什么方法
		private var _UIName:String="";					//UI的导出类名或者元件变量名
		private var _dragMCNameArr:Array=[];			//UI的导出类名或者元件变量名
		private var _LoadCompleteFun:Function;				//加载完成后执行的方法
		private var _LoadCancelFun:Function;				//加载取消执行的方法
		private var _container:DisplayObjectContainer;		//被加载的面板的主容器
		private var _dragEnable:Boolean=false;			//设置是否可拖动
		private var _isPopUpCenter:Boolean=false;			//每次弹出面板的时候是否居中显示
		private var _loadingStr:String="";					//loading显示的文字
		
		public function Panel_SM()
		{
			super();
		}
		
		/**
		 * 设置是否监听【关闭所有面板】的全局UI事件。
		 * @param b
		 * 
		 */
		public function AddToHideAll():void
		{
			_isAddToHideAll=true;
		}
		
		/**
		 * 取消监听【关闭所有面板】的全局UI事件。
		 * 
		 */
		public function removeFromHideAll():void
		{
			_isAddToHideAll=false;
			UIManager_SM.getInstance().removeEventListener(UIEvent.HIDE_ALL_PANEL,hideAll);
		}
		
		/**
		 * 获取是否监听【关闭所有面板】的全局UI事件。
		 * @return 
		 * 
		 */
		public function get isAddToHideAll():Boolean
		{
			return _isAddToHideAll;
		}
		
		private function hideAll(e:UIEvent):void
		{
			hide();
		}
		
		override public function show():void
		{
			if(_isAddToHideAll){
				UIManager_SM.getInstance().addEventListener(UIEvent.HIDE_ALL_PANEL,hideAll);
			}
			
			if(isPopUpCenter){
				PopUpUtils.centerInStage(this);
			}
			
			super.show();
		}
		
		override public function hide():void
		{
			UIManager_SM.getInstance().removeEventListener(UIEvent.HIDE_ALL_PANEL,hideAll);
			super.hide();
			stopLoader();
			
			if(_panelHideFun!=null){
				_panelHideFun();
				_panelHideFun=null;
			}
		}
		
		/**
		 * 
		 * @param container			这个panel的父级容器，加载完后会自动addChild
		 * @param url				面板UI的swf路径
		 * @param UIName			UI的导出类名或者元件变量名（如果留空，skin 将不会赋值也不会 addChild）
		 * @param getUIType			-1 	不取UI															GetUIType.none（如果为-1，skin 将不会被赋值也不会被 addChild）
		 * 							0 	代表直接取 Loader.content 作为 UI 								GetUIType.isLoaderContent
		 * 							1 	代表获取 Loader content 的子元件作为 UI   						GetUIType.fromLoaderContentByChildName
		 * 							2 	代表从 loader.contentLoaderInfo 的域中获取类并实例化作为 UI		GetUIType.getDefFromLoaderAppByName
		 * 
		 * @param completeFun		加载完面板后执行的方法
		 * @param isShowLoading		是否显示 Loading
		 * @param showCloseBtn		面板隐藏后执行的方法，只会执行一次，执行完会置 null
		 * @param cancelFun			取消加载时执行的方法(加载出错 IOError 也会调用此方法)
		 * @param panelHideFun		面板被hide时执行的方法
		 * @param isSaveLoader		是否保存loader，以便从 loader 获取其它类定义。请调用 Panel_SM 的 getClassFromLoaderByName 以获取类定义。
		 * @param dragEnable_		是否可拖动
		 * @param loadingStr		loading 条上显示的文字
		 * 
		 */
		public function loadUI(container:DisplayObjectContainer=null,
							   url:String="",
							   UIName:String="",
							   getUIType:uint=GetUIType.isLoaderContent,
							   completeFun:Function=null,
							   isShowLoading:Boolean=false,
							   showCloseBtn:Boolean=false,
							   cancelFun:Function=null,
							   panelHideFun:Function=null,
							   isSaveLoader:Boolean=false,
							   dragEnable_:Boolean=false,
							   loadingStr:String="正在加载……"
		):void
		{
			_container=container;
			_getUIType=getUIType;
			_UIName=UIName;
			_isShowLoading=isShowLoading;
			_panelHideFun=panelHideFun;
			_isSaveLoader=isSaveLoader;
			_LoadCompleteFun=completeFun;
			_LoadCancelFun=cancelFun;
			dragEnable=dragEnable_;
			_loadingStr=loadingStr;
			_isShowCloseBtn=showCloseBtn;
			
			if(_isShowLoading)
			{
				if(UIManager_SM.getInstance().loadingPanel){
					UIManager_SM.getInstance().loadingPanel.showCloseBtn(_isShowCloseBtn);
					UIManager_SM.getInstance().loadingPanel.addEventListener(UIEvent.CANCEL_LOADING,onLoadCancel);
					UIManager_SM.getInstance().loadingPanel.setPercent(0,0,_loadingStr);
					UIManager_SM.getInstance().loadingPanel.show();
				}
			}
			
			_loader=new Loader;
			_loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,onUIProgress);
			_loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onUIComplete);
			_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,onUIIOErr);
			_loader.load(new URLRequest(url));
		}
		
		private function onLoadCancel(e:UIEvent):void
		{
			if(_LoadCancelFun!=null){
				_LoadCancelFun();
			}
			
			removeAll();
		}
		
		/**
		 * 从 loader 获取类定义
		 * @param uiName
		 * @return 
		 * 
		 */
		public function getClassFromLoaderByName(uiName:String=""):Class
		{
			var c:Class;
			
			if(_loader){
				c=_loader.contentLoaderInfo.applicationDomain.getDefinition(uiName) as Class;
			}
			return c;
		}
		
		public function getLoader():Loader
		{
			return _loader;
		}
		
		public function clearLoader():void
		{
			if(_loader){
				removeLoaderEvent();
				_loader.unloadAndStop();
				_loader=null;
			}
			
			if(_container){
				_container=null;
			}
		}
		
		private function stopLoader():void
		{
			if(!_isSaveLoader){
				clearLoader();
			}else{
				removeLoaderEvent();
			}
		}
		
		private function removeLoaderEvent():void
		{
			if(_loader){
				_loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS,onUIProgress);
				_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,onUIComplete);
				_loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,onUIIOErr);
			}
		}
		
		private function onUIComplete(e:Event):void
		{
			var l:LoaderInfo = e.target as LoaderInfo;
			Trace_SM.trace("加载完成_21314f2："+l.url);
			
			if(UIManager_SM.getInstance().loadingPanel){
				UIManager_SM.getInstance().loadingPanel.hide();
			}
			
			removeLoaderEvent();
			_LoadCancelFun=null;
			setUI();
			
			if(_container){
				_container.addChild(this);
				_container=null;
			}
			
			if(_LoadCompleteFun!=null){
				_LoadCompleteFun();
				//_LoadCompleteFun=null;
			}
			
			dispatchEvent(new UIEvent(UIEvent.UI_LOAD_COMPLETE));
		}
		
		private function setUI():void
		{
			if(_UIName=="" && _getUIType!=0){
				return;
			}
			
			if(_getUIType==-1){
				return;
			}
			
			var ui:*;
			
			if(_getUIType==0)
			{
				ui=_loader.content as DisplayObject;
			}
			else if(_getUIType==1)
			{
				ui=DisplayObjectContainer(_loader.content).getChildByName(_UIName) as DisplayObject;
			}
			else if(_getUIType==2)
			{
				var c:Class=_loader.contentLoaderInfo.applicationDomain.getDefinition(_UIName) as Class;
				
				if(c){
					ui=new c;
				}
			}
			
			if(ui is DisplayObject){
				this.skin=ui;//设置面板皮肤
			}
		}
		
		protected function onUIProgress(e:ProgressEvent):void
		{
			if(_isShowLoading)
			{
				UIManager_SM.getInstance().loadingPanel.setPercent(e.bytesLoaded,e.bytesTotal);
			}
		}
		
		private function onUIIOErr(e:IOErrorEvent):void
		{
			var l:LoaderInfo = e.target as LoaderInfo;
			Trace_SM.trace("加载出错_2w314f2："+l.url);
			
			if(_isShowLoading)
			{
				UIManager_SM.getInstance().loadingPanel.setPercent(0,0,"很抱歉，加载出错了，请再试试吧");
			}
			
			if(_LoadCancelFun!=null){
				_LoadCancelFun();
			}
			
			dispatchEvent(new UIEvent(UIEvent.UI_LOAD_ERROR));
			removeAll();
		}
		
		public function removeAll():void
		{
			removeDragEvent();
			removeLoaderEvent();
			clearLoader();
			UIManager_SM.getInstance().removeEventListener(UIEvent.HIDE_ALL_PANEL,hideAll);
			UIManager_SM.getInstance().loadingPanel.removeEventListener(UIEvent.CANCEL_LOADING,onLoadCancel);
			_LoadCompleteFun=null;
			_LoadCancelFun=null;
		}
		
		/**
		 * 设置面板是否可拖动
		 * @param MCNameArr	MC 的变量名组成的数组
		 * 
		 */
		public function set dragEnable(b:Boolean):void
		{
			_dragEnable=b;
			
			if(b){
				this.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);
				this.addEventListener(MouseEvent.MOUSE_UP,onMouseUP);
			}else{
				removeDragEvent();
			}
		}
		
		public function get dragEnable():Boolean
		{
			return _dragEnable;
		}
		
		public function set isPopUpCenter(b:Boolean):void
		{
			_isPopUpCenter=b;
		}
		
		public function get isPopUpCenter():Boolean
		{
			return _isPopUpCenter;
		}
		
		private function onMouseDown(e:MouseEvent):void
		{
			this.startDrag(false);
		}
		
		private function onMouseUP(e:MouseEvent):void
		{
			this.stopDrag();
		}
		
		private function removeDragEvent():void
		{
			this.removeEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);
			this.removeEventListener(MouseEvent.MOUSE_UP,onMouseUP);
		}
	}
}